using System;
using System.Text;
using System.Collections.Generic;

namespace Demo_G.O.S.E.ServerEngine.AIEngine
{
    /// <summary>
    /// 
    /// </summary>
    public interface IMainContainer
    {
        void BornAgent( AgentID strName, ContainerID containerID, IADEPrincipal principal, string ownership, bool forceReplacement );
        void DeadAgent( AgentID strName );
        void SuspendedAgent( AgentID strName );
        void ResumedAgent( AgentID strName );
        void MovedAgent( AgentID agentID, ContainerID from, ContainerID to );
        void FrozenAgent( AgentID strName, ContainerID bufferContainer );
        void ThawedAgent( AgentID strName, ContainerID bufferContainer );

        void NewMTP( MTPDescriptor mtp, ContainerID containerID );
        void DeadMTP( MTPDescriptor mtp, ContainerID containerID );

        void ToolAdded( AgentID tool );
        void ToolRemoved( AgentID tool );

        ContainerID[] ContainerIDs();
        AgentID[] AgentNames();
        List<object> ContainerMTPs( ContainerID containerID );
        List<object> ContainerAgents( ContainerID containerID );
        ContainerID GetContainerID( AgentID agentID );
        NodeDescriptor GetContainerNode( ContainerID containerID );

        AgentDescriptor AcquireAgentDescriptor( AgentID agentID );
        void ReleaseAgentDescriptor( AgentID agentID );
    }


    //    public class SliceProxy : Slice
    //{

    //public SliceProxy() {
    //    this(null, null);
    //}

    //public SliceProxy(Service svc, Node n) {
    //    myService = svc;
    //    myNode = n;
    //}

    //public Service getService() {
    //    return myService;
    //}

    //public Node getNode() throws ServiceException {
    //    return myNode;
    //}

    //public void setNode(Node n) {
    //    myNode = n;
    //}

    ///**
    //   Try to serve an incoming horizontal command, routing it to
    //   a remote slice implementation.

    //   @param cmd The command to serve, possibly through the network.
    //*/
    //public VerticalCommand serve(HorizontalCommand cmd) {
    //    try {
    //    cmd.setReturnValue(myNode.accept(cmd));
    //    }
    //    catch(IMTPException imtpe) {
    //    cmd.setReturnValue(new ServiceException("An error occurred while routing the command to the remote implementation", imtpe));
    //    }
    //  // No local processing of this command is required
    //  return null;
    //}

    //private Node myNode;
    //private transient Service myService;

    //}

    public interface Service
    {

        //public const String NEW_NODE = "New-Node";
        //public const String DEAD_NODE = "Dead-Node";
        //public const String NEW_SLICE = "New-Slice";
        //public const String DEAD_SLICE = "Dead-Slice";
        //public const String NEW_REPLICA = "New-Replica";
        //public const String DEAD_REPLICA = "Dead-Replica";


        string getName();

        Slice getSlice( String name );

        Slice getLocalSlice();

        Slice[] getAllSlices();

        //Class getHorizontalInterface();

        /**
           Query by how many slices this service is composed at present.

           @return The number of slices belonging to this service. An
           active service must have at least one slice.
        */
        int getNumberOfSlices();


        //Filter getCommandFilter( bool direction );


        //Sink getCommandSink( bool side );


        string[] getOwnedCommands();

        //ServiceHelper getHelper( Agent a );

        //Behaviour getAMSBehaviour();

        //void init( AgentContainer ac, Profile p );

        //void boot( Profile p );

        void shutdown();

        object submit( VerticalCommand cmd );
    }

    /// <summary>
    /// 
    /// </summary>
    public interface Slice 
    {
        /// <summary>
        /// 
        /// </summary>
        Service Service
        {
            get;
        }
        /// <summary>
        /// 
        /// </summary>
        Node Node
        {
            get;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        VerticalCommand serve( HorizontalCommand cmd );
    }

    public interface HorizontalCommand /*: Command*/
    {
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        string Service
        {
            get;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        string Interaction
        {
            get;
        }
    }

    public interface VerticalCommand /*: Command */
    {
    }

    /// <summary>
    /// 
    /// </summary>
    public interface Node
    {
        /// <summary>
        /// 
        /// </summary>
        string setName
        {
            get;
            set;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        bool HasPlatformManager();
        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceName"></param>
        /// <param name="localSlice"></param>
        void ExportSlice( string serviceName, Slice localSlice );
        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceName"></param>
        void UnexportSlice( string serviceName );
        /// <summary>
        /// 
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        object Accept( HorizontalCommand cmd );
        /// <summary>
        /// 
        /// </summary>
        /// <param name="hang"></param>
        /// <returns></returns>
        bool Ping( bool hang );
        /// <summary>
        /// 
        /// </summary>
        void Interrupt();
        /// <summary>
        /// 
        /// </summary>
        void Exit();
        /// <summary>
        /// 
        /// </summary>
        /// <param name="deadPmAddress"></param>
        /// <param name="notifyingPmAddr"></param>
        void PlatformManagerDead( string deadPmAddress, string notifyingPmAddr );
    }

    /// <summary>
    /// 
    /// </summary>
    public interface ISDSIName
    {
        /// <summary>
        /// 
        /// </summary>
        string Algorithm
        {
            get;
        }

        /// <summary>
        /// 
        /// </summary>
        byte[] Encoded
        {
            get;
        }

        /// <summary>
        /// 
        /// </summary>
        string Format
        {
            get;
        }

        /// <summary>
        /// 
        /// </summary>
        string[] LocalNames
        {
            get;
        }

        /// <summary>
        /// 
        /// </summary>
        string LastLocalName
        {
            get;
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public interface IADEPrincipal : IComparable, IComparable<IADEPrincipal>
    {
        /// <summary>
        /// 
        /// </summary>
        string Name
        {
            get;
        }

        /// <summary>
        /// 
        /// </summary>
        ISDSIName SDSIName
        {
            get;
        }

        /// <summary>
        /// 
        /// </summary>
        byte[] Encoded
        {
            get;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        string ToString();

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        int GetHashCode();
    }

    /// <summary>
    /// 
    /// </summary>
    public interface Location
    {
        /// <summary>
        /// 
        /// </summary>
        string ID
        {
            get;
        }

        /// <summary>
        /// 
        /// </summary>
        string Name
        {
            get;
            set;
        }

        /// <summary>
        /// 
        /// </summary>
        string Protocol
        {
            get;
            set;
        }

        /// <summary>
        /// 
        /// </summary>
        string Address
        {
            get;
            set;
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public interface TransportAddress
    {
        /// <summary>
        /// 
        /// </summary>
        string Proto
        {
            get;
            set;
        }

        /// <summary>
        /// 
        /// </summary>
        string Host
        {
            get;
            set;
        }

        /// <summary>
        /// 
        /// </summary>
        string Port
        {
            get;
            set;
        }

        /// <summary>
        /// 
        /// </summary>
        string File
        {
            get;
            set;
        }

        /// <summary>
        /// 
        /// </summary>
        string Anchor
        {
            get;
            set;
        }
    }
}
